/*
 +-----------------------------------------------------------------------------------------------+
 | Project : UKAPI
 +-----------------------------------------------------------------------------------------------+
 | Project Description : Universal & Kernel API
 +-----------------------------------------------------------------------------------------------+
 | File Description :
 |   Math
 |                                                 
 +-----------------------------------------------------------------------------------------------+
 | Licence : MIT Licence
 +-----------------------------------------------------------------------------------------------+
 | Copyright (c) 2006 Olivier Vanhoucke
 | 
 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 | and associated documentation files (the "Software"), to deal in the Software without 
 | restriction, including without limitation the rights to use, copy, modify, merge, publish, 
 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
 | Software is furnished to do so, subject to the following conditions:
 | 
 | The above copyright notice and this permission notice shall be included in all copies or 
 | substantial portions of the Software.
 | 
 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 +-----------------------------------------------------------------------------------------------+
*/

/**
 * Inclusions standards
 */
#include <ukapi.h>

/**
 * Inclusions locales
 */
#include <math.h>

#define	MATH_RAND_LEN	607
#define	MATH_RAND_MASK	0x7fffffffL

void math_internal_rand_set_seed( int32_t seed );

/**
 * Static variables
 */
extern int32_t	g_math_rng_vec[MATH_RAND_LEN];
extern pint32_t	g_math_rng_tap;
extern pint32_t	g_math_rng_feed;

int32_t math_rand()
{
	int32_t x;

	//lock(&lk);

	g_math_rng_tap--;

	if ( g_math_rng_tap < g_math_rng_vec ) 
	{
		if ( g_math_rng_feed == null ) 
		{
			math_internal_rand_set_seed( 1 );
			g_math_rng_tap--;
		}
		g_math_rng_tap += MATH_RAND_LEN;
	}

	g_math_rng_feed--;
	
	if ( g_math_rng_feed < g_math_rng_vec )
	{
		g_math_rng_feed += MATH_RAND_LEN;
	}
	x = (*g_math_rng_feed + *g_math_rng_tap) & MATH_RAND_MASK;

	*g_math_rng_feed = x;

	//unlock(&lk);

	return x;
}